package utils.time;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import czolgisci.events.TickEvent;

/**
 * Zegar wysyłający sygnały do zarejestrowanych obiektów (add/remove Listener)
 * co pewien okres czasu (interval)
 * 
 * @author kasztan
 * @version 1.01
 */
public class Clock
{
	public Clock()
	{
		listeners = new ArrayList<IClockListener>();
		ticker = new Timer();
		interval = DEFAULT_INTERVAL;
		delay = DEFAULT_DELAY;
		started = false;
	}
	
	public void start()
	{
		if(started)
			return;
		started = true;
		ticker.schedule(task, delay, interval);
	}

	public void start(long delay)
	{
		if(started)
			return;
		this.delay = delay;
		start();
	}

	/**
	 * start zliczania
	 * 
	 * @param delay
	 *            opóźnienie startu (w milisekundach)
	 * @param interval
	 *            interwał zegara
	 */
	public void start(long delay, long interval)
	{
		if(started)
			return;
		this.delay = delay;
		this.interval = interval;
		start();
	}

	/**
	 * Zatrzymanie zliczania
	 */
	public void stop()
	{
		ticker.cancel();
		started = false;
	}

	/**
	 * Chwilowe wstrzymanie liczenia, pauza
	 */
	public void pause()
	{
		paused = true;
	}

	/**
	 * Ponowny start zegara po pauzie
	 */
	public void resume()
	{
		paused = false;
	}

	/**
	 * wymuszenie rozesłania zdarzenia TickEvent do wszystkich zarejestrowanych
	 * obiektów
	 */
	public void tick()
	{
		if(paused)
			return;
		
		for (IClockListener listener : listeners)
		{
			listener.onTick(new TickEvent());
		}
	}

	/**
	 * Rejestruje obiekt nasłuchujący
	 * 
	 * @param listener
	 * @return true, jesli listener zostal dodany, false jesli byl juz w bazie
	 */
	public boolean addListener(IClockListener listener)
	{
		if(listeners.contains(listener))
			return false;
		listeners.add(listener);
		return true;
	}

	/**
	 * Usuwa z rejestru obiekt nasłuchujący
	 * 
	 * @param listener
	 *            obiekt do usunięcia
	 * @return true, jesli listener zostal usuniety
	 */
	public boolean removeListener(IClockListener listener)
	{
		return listeners.remove(listener);
	}
	
	///////////////////////////////////////////////
	///////////////  PRIVATE  /////////////////////
	///////////////////////////////////////////////
	
	private ArrayList<IClockListener> listeners;
	private long interval;
	private long delay;
	private boolean paused;
	private boolean started = false;
	private static final long DEFAULT_INTERVAL = 5;
	private static final long DEFAULT_DELAY = 100;
	private Timer ticker;
	private TimerTask task = new TimerTask()
	{
		public void run() {
			//EventQueue.invokeLater(...);
			tick();
		}
	};
}
